package com.mybatis.study.executor;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.mybatis.study.ReflectionUtil;
import com.mybatis.study.config.Configuration;
import com.mybatis.study.config.MapperStatement;
import com.mybatis.study.model.FieldAndType;

public class DefaultExecutor implements Executor {
	
	private final Configuration config;
	

	public DefaultExecutor(Configuration config) {
		super();
		this.config = config;
	}



	public <E> List<E> query(MapperStatement mapperStatement, Object param) {
		// TODO Auto-generated method stub
		System.out.println(mapperStatement.getSql());
		
		
		List<E> ret =new ArrayList<E>();//定义返回类型
		//加载驱动软件
		try {
			Class.forName(config.getJdbcDriver());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Connection onConnection=null;
		PreparedStatement preparedStatement=null;
		ResultSet resultSet=null;
		
		try {
			//获取链接 
			onConnection=DriverManager.getConnection(config.getJdbcUrl(), config.getJdbcUsername(),config.getJdbcPassword());
			//创建解析器，从mapperStatement取得sql语句预编译
			preparedStatement=onConnection.prepareStatement(mapperStatement.getSql().trim());
			//处理sql的占位符
			paramterize(preparedStatement, param);
			//执行
			resultSet=preparedStatement.executeQuery();
			handlerResultSet(resultSet, ret, mapperStatement.getResultType(),mapperStatement.getFieldToMap());
			//处理sql的占位符
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			
			try {
				onConnection.close();
			    preparedStatement.close();
			    if(resultSet!=null) {
				   resultSet.close();
			    }
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return ret;
	}
	
	private void paramterize(PreparedStatement preparedStatement,Object param) throws SQLException {
		if(param instanceof String) {
			preparedStatement.setString(1, ((String) param).trim());
		}
	}
	
	private <E> void  handlerResultSet(ResultSet resultSet ,List<E> list,String className,Map<String, FieldAndType> fields) {
		Class<E> clazz=null;
		try {
			//通过反射获取类对象
			clazz=(Class<E>) Class.forName(className);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			while(resultSet.next()) {
				try {
					Object enity=clazz.newInstance();
					ReflectionUtil.setProPtoBeanFromResultSet(enity, resultSet,fields);
					list.add((E) enity);
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}
